package com.ebt.m.commons.buscomponent.listview.pulltorefresh;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.animation.Animation;
import android.view.animation.Transformation;

import com.ebt.m.commons.R;


/**
 * Created by andy on 2017/9/20.
 */

public class ZyjRefreshView extends BaseRefreshView {
    private static final float HEIGHT_RATIO = 1.0f;
    private static final float BUILDING_INITIAL_SCALE = 1.0f;
    private static final float BUILDING_FINAL_SCALE = 1.2f;

    private PullToRefreshView mParent;

    private Matrix mMatrix;

    private Context mContext;

    private Animation mHatAnimation;

    private Bitmap mHat;

    private Paint mBackgroundPaint;
    private Paint mShadowPaint;
    private Paint mTextPaint;

    private boolean isRefreshing = false;

    private float mShadowBottomOffset;

    private float mHatTransAngle;
    private float mPercent;

    private int mHatWidth;
    private int mShadowWidth = 25;
    private int mShadowHeight = 4;
    private float leftPartOffsetX;
    private float mTestMarginLeft = 40;

    /**
     * height of landscape
     */
    private int mSenceHeight;
    /**
     * width of landscape
     */
    private int mScreenWidth;
    /**
     * distance between bottom of landscape and top of landscape
     */
    private int mTop;
    /**
     * max distance between bottom of landscape and top of landscape
     */
    private int totalDistance;

    public ZyjRefreshView(final PullToRefreshView layout) {
        super(layout);

        mParent = layout;
        mMatrix = new Matrix();
        mContext = getContext();
        setupAnimations();
        setupPaint();
        layout.post(new Runnable() {
            @Override
            public void run() {
                initialDimens(layout.getWidth());
            }
        });
    }

    @Override
    protected void initialDimens(int viewWidth) {
        if (viewWidth <= 0 || viewWidth == mScreenWidth) return;

        createBitmaps();

        mScreenWidth = viewWidth;
        mSenceHeight = (int) (HEIGHT_RATIO * mScreenWidth);

        mTop = -mParent.getTotalDragDistance();
        totalDistance = -mTop;

        mShadowBottomOffset = -mTop / 2 - mHat.getHeight() / 2;

        mHatWidth = mHat.getWidth();

        leftPartOffsetX = mScreenWidth / 2 - mHatWidth / 2 - mTestMarginLeft;
    }

    private void createBitmaps() {
        mHat = CreateBitmapFactory.getBitmapFromImage(R.drawable.icon_pull_refresh, mContext);
    }

    @Override
    public void draw(Canvas canvas) {
        if (mScreenWidth <= 0) return;

        final int saveCount = canvas.save();

        canvas.translate(0, mTop);
        canvas.clipRect(0, -mTop, mScreenWidth, mParent.getTotalDragDistance());
        canvas.drawRect(0, -mTop, mScreenWidth, mParent.getTotalDragDistance(), mBackgroundPaint);

        drawShadow(canvas);
        drawHat(canvas);
        drawLoadingText(canvas);
        canvas.restoreToCount(saveCount);
    }

    /**
     * Draw  shadow
     *
     * @param canvas canvas
     */
    private void drawShadow(Canvas canvas) {

        float dragPercent = Math.min(1f, Math.abs(mPercent));
        final float offsetY = totalDistance - mShadowBottomOffset;
        RectF rectF = new RectF();
        rectF.left = leftPartOffsetX - (mHatTransAngle == 0.0f ? mShadowWidth * dragPercent : mShadowWidth * (1 - mHatTransAngle));
        rectF.top = offsetY - (mHatTransAngle == 0.0f ? mShadowHeight * dragPercent : mShadowHeight * (1 - mHatTransAngle)) - 2;
        rectF.right = leftPartOffsetX + (mHatTransAngle == 0.0f ? mShadowWidth * dragPercent : mShadowWidth * (1 - mHatTransAngle));
        rectF.bottom = offsetY + (mHatTransAngle == 0.0f ? mShadowHeight * dragPercent : mShadowHeight * (1 - mHatTransAngle));
        canvas.drawOval(rectF, mShadowPaint);
    }

    private void drawLoadingText(Canvas canvas) {
        float dragPercent = Math.min(1f, Math.abs(mPercent));
        String text = isRefreshing ? "正在刷新" : (dragPercent >= 1.0f ? "松开刷新" : "下拉刷新");
        canvas.drawText(text, mScreenWidth / 2 - mTestMarginLeft / 2, totalDistance - mShadowBottomOffset - 20, mTextPaint);
    }

    /**
     * Draw hat
     *
     * @param canvas canvas
     */
    private void drawHat(Canvas canvas) {
        final Matrix matrix = mMatrix;
        matrix.reset();

        float dragPercent = Math.min(1f, Math.abs(mPercent));

        final float offsetX = leftPartOffsetX - mHatWidth / 2;
        final float offsetY = mShadowBottomOffset * dragPercent - totalDistance / 4 * mHatTransAngle;
        matrix.postTranslate(offsetX, offsetY);
        canvas.drawBitmap(mHat, matrix, null);
    }

    @Override
    protected void setupAnimations() {
        AnimationFactory factory = new AnimationFactory();
        mHatAnimation = factory.getSunTranslate(new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
                float value = setVariable(interpolatedTime);
                mHatTransAngle = value > 0.5f ? ((1 - value) * 2) : (value * 2);
            }
        });
        mHatAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                resetOrigins();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }
        });
    }

    private void setupPaint() {
        mBackgroundPaint = new Paint();
        mBackgroundPaint.setColor(Color.WHITE);
        mBackgroundPaint.setStyle(Paint.Style.FILL);

        mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mShadowPaint.setColor(Color.parseColor("#dedede"));
        mShadowPaint.setStyle(Paint.Style.FILL);

        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setColor(Color.parseColor("#bbbbbb"));
        mTextPaint.setTextSize(40);
    }

    @Override
    public void setBounds(int left, int top, int right, int bottom) {
        super.setBounds(left, top, right, mSenceHeight + top);
    }

    @Override
    public void setPercent(float percent, boolean invalidate) {
        setPercent(percent);
    }

    private void setPercent(float percent) {
        this.mPercent = percent;
    }

    @Override
    public void offsetTopAndBottom(int offset) {
        mTop += offset;
        invalidateSelf();
    }

    @Override
    public void start() {
        mHatAnimation.reset();
        isRefreshing = true;
        mParent.startAnimation(mHatAnimation);
    }

    @Override
    public void stop() {
        mParent.clearAnimation();
        isRefreshing = false;
    }

    @Override
    public boolean isRunning() {
        return false;
    }

    private float setVariable(float value) {
        invalidateSelf();
        return value;
    }

    private void resetOrigins() {
        setPercent(0);
        mHatTransAngle = setVariable(0);
    }

}
